package com.ivncorp.evnproject.helpers;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.IBinder;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesClient;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.LocationClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;

public class LocationTracker extends Service implements LocationListener,
		GooglePlayServicesClient.ConnectionCallbacks,
		GooglePlayServicesClient.OnConnectionFailedListener {

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return null;
	}

	// Debugging tag for the application
	public static final String APPTAG = "LocationSample";

	// Name of shared preferences repository that stores persistent state
	public static final String SHARED_PREFERENCES = "com.example.android.location.SHARED_PREFERENCES";

	// Key for storing the "updates requested" flag in shared preferences
	public static final String KEY_UPDATES_REQUESTED = "com.example.android.location.KEY_UPDATES_REQUESTED";

	/*
	 * Define a request code to send to Google Play services This code is
	 * returned in Activity.onActivityResult
	 */
	public final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

	/*
	 * Constants for location update parameters
	 */
	// Milliseconds per second
	public static final int MILLISECONDS_PER_SECOND = 1000;

	// The update interval
	public static final int UPDATE_INTERVAL_IN_SECONDS = 5;

	// A fast interval ceiling
	public static final int FAST_CEILING_IN_SECONDS = 1;

	// Update interval in milliseconds
	public static final long UPDATE_INTERVAL_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
			* UPDATE_INTERVAL_IN_SECONDS;

	// A fast ceiling of update intervals, used when the app is visible
	public static final long FAST_INTERVAL_CEILING_IN_MILLISECONDS = MILLISECONDS_PER_SECOND
			* FAST_CEILING_IN_SECONDS;

	// Create an empty string for initializing strings
	public static final String EMPTY_STRING = new String();
	// A request to connect to Location Services
	private LocationRequest mLocationRequest;

	// Stores the current instantiation of the location client in this object
	private LocationClient mLocationClient;

	private Context context;
	private Location location;
	boolean mUpdatesRequested = false;
	double latitude;
	double longitude;

	public LocationTracker(Context _context) {
		this.context = _context;
		mLocationRequest = LocationRequest.create();
		mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
		// Use high accuracy
		mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
		// Set the interval ceiling to one minute
		mLocationRequest
				.setFastestInterval(FAST_INTERVAL_CEILING_IN_MILLISECONDS);
		// Note that location updates are off until the user turns them on
		mUpdatesRequested = false;

		mLocationClient = new LocationClient(context, this, this);
		StartLocation();
		// getLocation();

	}

	public void StopLocation() {
		// If the client is connected
		if (mLocationClient.isConnected()) {
			stopPeriodicUpdates();
		}
		// After disconnect() is called, the client is considered "dead".
		mLocationClient.disconnect();
	}

	public void StartLocation() {
		mLocationClient.connect();
	}

	public boolean servicesConnected() {

		// Check that Google Play services is available
		int resultCode = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(context);

		// If Google Play services is available
		if (ConnectionResult.SUCCESS == resultCode) {

			return true;
			// Google Play services was not available for some reason
		} else {

			return false;
		}
	}

	public Location getLocation() {

		// If Google Play Services is available
		if (servicesConnected()) {

			// Get the current location
			location = mLocationClient.getLastLocation();

			// Display the current location in the UI
		}
		return location;
	}

	public void startUpdates() {
		mUpdatesRequested = true;

		if (servicesConnected()) {
			startPeriodicUpdates();
		}
	}

	public void stopUpdates() {
		mUpdatesRequested = false;

		if (servicesConnected()) {
			stopPeriodicUpdates();
		}
	}

	@Override
	public void onConnected(Bundle bundle) {
		if (mUpdatesRequested) {
			startPeriodicUpdates();
		}
	}

	@Override
	public void onDisconnected() {

	}

	@Override
	public void onConnectionFailed(ConnectionResult connectionResult) {
		/*
		 * if (connectionResult.hasResolution()) { try {
		 * connectionResult.startResolutionForResult(context,
		 * LocationUtils.CONNECTION_FAILURE_RESOLUTION_REQUEST); } catch
		 * (IntentSender.SendIntentException e) {
		 * 
		 * // Log the error e.printStackTrace(); } } else {
		 * 
		 * }
		 */
	}

	@Override
	public void onLocationChanged(Location location) {

	}

	private void startPeriodicUpdates() {
		mLocationClient.requestLocationUpdates(mLocationRequest, this);

	}

	private void stopPeriodicUpdates() {
		mLocationClient.removeLocationUpdates(this);

	}

	public String getLatitude() {

		String result = null;

		if (location != null) {
			latitude = location.getLatitude();
			// convert
			int num1Lat = (int) Math.floor(latitude);
			int num2Lat = (int) Math.floor((latitude - num1Lat) * 60);
			double num3Lat = (latitude - ((double) num1Lat + ((double) num2Lat / 60))) * 3600000;
			result = num1Lat + "/1," + num2Lat + "/1," + num3Lat + "/1000";
		}

		return result;
	}

	public String getLatitudeRef() {
		return latitude < 0.0d ? "S" : "N";
	}

	public String getLongitude() {
		String result = null;
		if (location != null) {
			longitude = location.getLongitude();
			// convert
			int num1Lat = (int) Math.floor(longitude);
			int num2Lat = (int) Math.floor((longitude - num1Lat) * 60);
			double num3Lat = (longitude - ((double) num1Lat + ((double) num2Lat / 60))) * 3600000;
			result = num1Lat + "/1," + num2Lat + "/1," + num3Lat + "/1000";
		}
		return result;
	}

	public String getLongitudeRef() {
		return longitude < 0.0d ? "W" : "E";
	}

}
